package com.apes.pi.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.framework.api.DomainService;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.plugin.event.Listener;
import com.apes.framework.util.MapUtil;
import com.apes.pi.model.Timestamp;
import com.apes.pi.repository.TimestampRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @ClassName PiManager
 * @Description TODO
 * @Author pengyb
 * @Date 2019/12/6 11:03
 * @Version 1.0
 **/
@Component
public class PiManager extends DomainService {

    TimestampRepository timestampRepository;

    @Autowired
    private void setTimestampRepository(TimestampRepository timestampRepository) {
        this.timestampRepository = timestampRepository;
    }

    public static final String CONST_SAVE = "S";
    public static final String CONST_UPDATE = "U";
    public static final String PI_YYERP = "pi.yyerp.invoke";
    public static final String PI_LOCAL_YYERP = "pi.yyerpLocal.invoke";

    /**
     * 同步新框架
     *
     * @param body
     */
    public void synEsb(String method, Object body) {
        //同步至新系统
        Object invoke = invoke(method, body);
        JSONObject header = JSONObject.parseObject(invoke.toString()).getJSONObject("header");
        if (!"success".equals(header.get("code"))) throw new RuntimeException(header.getString("message"));
    }

    /**
     * 获取erp对应数据版本号(时间戳)
     *
     * @param body
     * @param method
     * @return
     */
    public String getVersion(String method, Object body) {
        Object getDate = invoke(PI_YYERP, mapper("body", body, "headers", MapUtil.mapper("method", method)));
        JSONObject parseObject = JSONObject.parseObject(getDate.toString());
        if (!parseObject.getBoolean("success")) throw new RuntimeException(parseObject.getString("msg"));
        JSONArray parseArray = JSONArray.parseArray(parseObject.get("obj").toString());
        if (parseArray == null || parseArray.size() == 0) throw new RuntimeException("ERP查无此数据，更新失败！");
        JSONObject data = (JSONObject) (parseArray).stream().findAny().get();
        return data.getString("TS01");
    }

    /**
     * 同synErp，提供给不可以依赖apes-misc包用
     * @param simpleRequest
     * @return
     */
    @Listener(topic = "event:pi.synErpListener")
    public JSONObject synErpListener(SimpleRequest simpleRequest) {
        JSONObject getData = JSON.parseObject(simpleRequest.getData().toString());
        if (getData.getJSONArray("data").size() == 0) {
            throw new RuntimeException("传入数据格式不能为空！");
        }
        Map data = mapper("body", getData.getJSONArray("data").getJSONObject(0), "headers", MapUtil.mapper("method", getData.getString("method")));
        Object result = invoke(PI_YYERP , data);
        JSONObject resultJo = JSONObject.parseObject(result.toString());
        if (!resultJo.getBoolean("success")) throw new RuntimeException(resultJo.getString("msg"));
        return resultJo;
    }

    /**
     * 同步erp
     *
     * @param body
     * @param method
     */
    public JSONObject synErp(String method, Object body) {
        Map data = mapper("body", body, "headers", MapUtil.mapper("method", method));
        Object result = invoke(PI_YYERP, data);
        JSONObject resultJo = JSONObject.parseObject(result.toString());
        if (!resultJo.getBoolean("success")) throw new RuntimeException(resultJo.getString("msg"));
        return resultJo;
    }

    /**
     * 同步app
     * @param body
     * @param method
     */
    public JSONObject synApp(String method, Object body) {
        Map data = mapper("body", body, "headers", MapUtil.mapper("method", method));
        Object result = invoke("pi.app.ext", data);
        JSONObject resultJo = JSONObject.parseObject(result.toString());
        if ( resultJo.containsKey("success") && !resultJo.getBoolean("success")) {
            JSONObject errorJson = resultJo.getJSONObject("data");
            throw new RuntimeException( errorJson.getString("name") + "-" + errorJson.getString("message"));
        } else if (!resultJo.containsKey("success") && resultJo.getString("body").contains("异常")) {
            // 处理这种报错  {"header":{"code":"isp.xxx-service-unavailable","message":" 获取APP签名报错：null"},"body":"调用服务异常。"}
            JSONObject header = resultJo.getJSONObject("header");
            throw new RuntimeException( header.getString("message") + "，请求参数为：" + JSONObject.toJSONString(data) );
        }
        return resultJo;
    }

    /**
     * 同步app时通知
     * @param request
     * @return
     */
    @Listener(topic = "event:pi.app.synAppNotify")
    public JSONObject synAppNotify(SimpleRequest request){
        Map map = request.getMap();
        String method = (String) map.get("method");
        Date date = (Date) map.get("timestamp");
        Map newMap = new HashMap();
        newMap.put("yyerpApiName", method);
        newMap.put("timestamp", date.getTime());
        return this.synApp("v1/yyerp-sync/notify", newMap);
    }

    /**
     * 同步app
     * 当包相互依赖或底层调上层包时调用
     *
     * @param request
     */
    @Listener(topic = "event:pi.app.synApp")
    public JSONObject synApp(SimpleRequest request) {
        Map map = request.getMap();
        String method = (String) map.get("method");
        map.remove("method");
        return this.synApp(method, map);
    }



    /**
     * PI同步调用老系统数据(定时任务用)
     *
     * @param interfaceId
     * @return
     */
    public JSONArray timedTaskSynErp(String interfaceId) {
        // 取接口调用的时间戳
        Timestamp timestamp = timestampRepository.findOne(interfaceId);
        Map data = new HashMap();
        data.put("interfaceMethod", interfaceId);
        if (timestamp != null) {
            data.put("TIMESTAMP", timestamp.getTime());
        } else {
            data.put("TIMESTAMP", LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE) + ".000000.000");
        }
        JSONObject resultObj = synErp(interfaceId, data);
        JSONArray resultArray = JSONArray.parseArray(resultObj.getString("obj"));

        // 更新最后的时间戳到 res_timestamp 表记录, 下次定时任务用
        if (resultArray.size() > 0) {

            // 获取最后的时间戳
            String lastTimeTamp = resultArray.getJSONObject(resultArray.size() - 1).getString("TS01");
            if (timestamp == null) {
                timestamp = new Timestamp();
            }
            timestamp.setId(interfaceId);
            timestamp.setType("timestamp");
            timestamp.setTime(lastTimeTamp);
            timestampRepository.save(timestamp);
        }
        return resultArray;
    }

    /**
     * PI同步调用老系统数据(定时任务用)
     *
     * @param interfaceId
     * @return
     */
    public JSONArray timedTaskSynErpByConditions(String interfaceId,String conditions) {
        // 取接口调用的时间戳
        Timestamp timestamp = timestampRepository.findOne(interfaceId);
        Map data = new HashMap();
        data.put("interfaceMethod", interfaceId);
        if (timestamp != null) {
            data.put("TIMESTAMP", timestamp.getTime());
            data.put("conditions", timestamp.getConditions());
        } else {
            data.put("TIMESTAMP", LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE) + ".000000.000");
        }
        JSONObject resultObj = synErp(interfaceId, data);
        JSONArray resultArray = JSONArray.parseArray(resultObj.getString("obj"));

        // 更新最后的时间戳到 res_timestamp 表记录, 下次定时任务用
        if (resultArray.size() > 0) {

            // 获取最后的时间戳
            String lastTimeTamp = resultArray.getJSONObject(resultArray.size() - 1).getString("TS01");
            if (timestamp == null) {
                timestamp = new Timestamp();
            }
            timestamp.setId(interfaceId);
            timestamp.setType("timestamp");
            timestamp.setConditions(resultArray.getJSONObject(resultArray.size() - 1).getString(conditions));
            timestamp.setTime(lastTimeTamp);
            timestampRepository.save(timestamp);
        }
        return resultArray;
    }
    /**
     * 获取erp对应数据
     *
     * @param body
     * @param method
     * @return
     */
    public JSONObject erpFindOneData(String method, Object body,String note) {
        Object getDate = invoke(PI_YYERP, mapper("body", body, "headers", MapUtil.mapper("method", method)));
        JSONObject parseObject = JSONObject.parseObject(getDate.toString());
        if (!parseObject.getBoolean("success")) throw new RuntimeException(parseObject.getString("msg"));
        JSONObject data = JSONObject.parseObject(parseObject.get("obj").toString());
        return data;
    }
}

